//
//  File.swift
//
//
//  Created by didi on 2022/9/14.
//

import Fluent
import Molecular
import MolecularRedirectObjects
import Vapor

extension Redirect.Rule.List: Content { }
extension Redirect.Rule.Detail: Content { }

struct RedirectRuleApiController: ApiController {
    typealias ApiModel = Redirect.Rule
    typealias DatabaseModel = RedirectRuleModel

    typealias CreateContext = Redirect.Rule.Create

    func listOutput(_ req: Request, _ models: [RedirectRuleModel]) async throws -> [Redirect.Rule.List] {
        models.map {
            .init(id: $0.uuid, source: $0.source, destination: $0.destination, statusCode: $0.statusCode, notes: $0.notes)
        }
    }

    func detailOutput(_ req: Request, _ model: DatabaseModel) async throws -> Redirect.Rule.List {
        .init(id: model.id!,
              source: model.source,
              destination: model.destination,
              statusCode: model.statusCode,
              notes: model.notes)
    }

    func createInput(_ req: Request, _ model: DatabaseModel, _ input: Redirect.Rule.Create) async throws {
        model.source = input.source
        model.destination = input.destination
        model.statusCode = input.statusCode
        model.notes = input.notes
    }

    func updateInput(_ req: Request, _ model: DatabaseModel, _ input: Redirect.Rule.Update) async throws {
        model.source = input.source
        model.destination = input.destination
        model.statusCode = input.statusCode
        model.notes = input.notes
    }

    func patchInput(_ req: Request, _ model: DatabaseModel, _ input: Redirect.Rule.Patch) async throws {
        model.source = input.source
        model.destination = input.destination
        model.statusCode = input.statusCode
        model.notes = input.notes
    }

    func validators(optional: Bool) -> [AsyncValidator] {
        [
            KeyedContentValidator<String>.required("source", optional: optional),
            KeyedContentValidator<String>.required("destination", optional: optional),
            KeyedContentValidator<Int>.contains("statusCode", Redirect.Rule.StatusCode.allCases.map(\.rawValue), optional: optional),
        ]
    }
}
